#include <iostream>
#include <vector>
#include <list>
#include <string>

using namespace std;

//菜单项类
class MenuItem
{
public:
    MenuItem(){}
    MenuItem(string na, string descrip, double pric)
    {
        name = na;
        description = descrip;
        price = pric;
    }

    string getName()
    {
        return name;
    }

    string getDescription()
    {
        return description;
    }

    double getPrice()
    {
        return price;
    }
private:
    string name;
    string description;
    double price;
};

/*迭代器基类*/
class Iterator
{
public:
    /*是否有下一个一个菜单*/
    virtual bool hasNext(){throw "ERROR";};
    /*取下一个菜单*/
    virtual MenuItem next(){throw "ERROR";};
};

/*煎饼屋菜单迭代器*/
class PancakeHouseMenuIterator : public Iterator
{
public:
    PancakeHouseMenuIterator(list<MenuItem> item)
    {
        items = item;
        iter = items.begin();
    }
    MenuItem next()
    {
        MenuItem menuItem = *iter;
        ++iter;
        return menuItem;
    }

    bool hasNext()
    {
        if(iter == items.end())
        {
            return false;
        }
        else
        {
            return true;
        }
    }
private:
    list<MenuItem> items;
    list<MenuItem>::const_iterator iter;
};

/*午餐店菜单迭代器*/
class DinerMenuIterator : public Iterator
{
public:
    DinerMenuIterator(vector<MenuItem> item):position(0)
    {
        items = item;
    }
    MenuItem next()
    {
        MenuItem menuItem = items[position];
        position = position + 1;
        return menuItem;
    }

    bool hasNext()
    {
        if(position >= items.size())
        {
            return false;
        }
        else
        {
            return true;
        }
    }
private:
    vector<MenuItem> items;
    unsigned int position;
};

/*餐单基类*/
class Menu
{
public:
    /*创建迭代器*/
    virtual Iterator* createIterator(){throw "ERROR";}
};

/*煎饼屋餐单类*/
class PancakeHouseMenu : public Menu
{
public:
    PancakeHouseMenu()
    {
        addItem("K&B'S Breakfase","pacakes with eggs",2.99);
        addItem("Buleberry Breakfase","pacakes with buleberries",3.99);
    }
    /*增加菜单*/
    void addItem(string na, string descrip, double ric)
    {
        MenuItem menuItem(na,descrip,ric);
        menuItems.push_back(menuItem);
    }
    /*创建PancakeHouseMenuIterator迭代器*/
    Iterator* createIterator()
    {
        return new PancakeHouseMenuIterator(menuItems);
    }
private:
    list<MenuItem> menuItems;
};

/*午餐点餐单类*/
class DinerMenu : public Menu
{
public:
    DinerMenu()
    {
        addItem("Vegetarian BLT", "Bacon with lettuce", 2.99);
        addItem("BLT", "Bacon with tomato", 3.99);
    }
    void addItem(string na, string descrip, double ric)
    {
        MenuItem menuItem(na,descrip,ric);
        menuItems.push_back(menuItem);
    }
    Iterator* createIterator()
    {
        return new DinerMenuIterator(menuItems);
    }
private:
    vector<MenuItem> menuItems;
};

/*服务生类*/
class Waitress
{
public:
    Waitress(Menu* p_PancakeHouseMenu, Menu* p_DinerMenu)
    {
        pPancakeHouseMenu = p_PancakeHouseMenu;
        pDinerMenu = p_DinerMenu;
    }
    /*打印菜单*/
    void printMenu()
    {
        Iterator* pPancakeHouseIterator = pPancakeHouseMenu->createIterator();
        Iterator* pDinerIterator = pDinerMenu->createIterator();

        cout << "Menu"<< endl <<"----"<<endl << "BREAKFAST" <<endl;
        printMenu(pPancakeHouseIterator);
        cout << "LUNCH" << endl;
        printMenu(pDinerIterator);
    }
    /*因为抽象出迭代器，所以可以根据迭代器打印菜单*/
    void printMenu(Iterator* iter)
    {
        while(iter->hasNext()){
            MenuItem menuItem = (MenuItem)iter->next();
            cout << menuItem.getName() << " "<< menuItem.getPrice()<<"  " 
            << menuItem.getDescription() << endl;
        }
    }
private:
    Menu* pPancakeHouseMenu;
    Menu* pDinerMenu;
};

/*客户代码*/
int main()
{
    Menu* pPancakeHouseMenu = new PancakeHouseMenu();
    Menu* pDinerMenu = new DinerMenu();

    Waitress waitress(pPancakeHouseMenu,pDinerMenu);
    waitress.printMenu();
		
    return 0;
}
